﻿


using IotClientService;
using IotContract.Enums;
using IotContract.Interfaces;
using System.Diagnostics;
using XT.Common.Config;
using XT.Common.Enums;
using XT.Common.Extensions;
using XT.Common.Interfaces;
using XT.Common.Models.SignalR;
using XT.Common.Services;
using XT.Common.WinServices;

namespace IotClientWeb.Services;

public class WebWinService : TimerService
{
    
    private ILogService _logService;
    private ISignalRService _signalRService;
    private IClientMainManager _clientMainManager;

    private string _programName = string.Empty;
   


    private IConnectDataService _connectDataService;

    // 程序id
    private long _programId = 0;
    
    private bool _isExecute = false;
    // 程序状态
    private ProgramStatusType _status = ProgramStatusType.Offline;

    /// <summary>
    /// 错误
    /// </summary>
    private string _error = string.Empty;

    private CancellationTokenSource? _cancellationTokenSource;
    public WebWinService(ILogService logService, ISignalRService signalRService, IConnectDataService connectDataService, IClientMainManager manager)
    {
        _logService = logService;
        _signalRService = signalRService;

        _connectDataService = connectDataService;
        _clientMainManager = manager;

      

        // 程序名称
        _programName = AppSettings.GetValue("ProgramName");

    }


    public async override Task Start()
    {
        StartBase();
        _cancellationTokenSource = new CancellationTokenSource();

      
       
        _error = string.Empty;

        // 开始进行数据添加
        var programResult = await _connectDataService.AddProgram(new IotContract.Models.Clients.ClientConnectCommand
        {
            IPAddress = WindowProcessService.GetLocalIp(),
            ProgramType = (int)IotProgramType.IotClientWeb,
            RunPath = Process.GetCurrentProcess().MainModule.FileName
        });

        if (programResult.Item2.IsNotNullOrEmpty()) { _logService.LogError($"Error Run {programResult.Item2}"); }

        _programId = programResult.Item1.Id;
        _programName = programResult.Item1.Name;



        var result = await ConnectSignalR();



        if (!result)
        {
            _error = "SignalR connect error";
            _logService.LogError($"Please Check RemoteAddress In appsettins.json，Not Connect Ecs Api");
        }

       // 上报状态，数据库
        Timers.Start("ReportStatus", 60000, async () =>
        {



           
                if (_programId > 0)
                {
                     await _connectDataService.CommitStatus(new IotContract.Models.Clients.ClientStatusCommand
                    {
                        ProgramId = _programId,
                        Name = _programName,
                        Status = _status,
                        StatusDes = _error

                    });

                   
                }
            

          

        });


        if (_programId > 0)
        {
            // 上报状态，如果报错，启动失败
            await _connectDataService.CommitStatus(new IotContract.Models.Clients.ClientStatusCommand
            {
                ProgramId = _programId,
                Name = _programName,
                Status = ProgramStatusType.Online,
                StatusDes = _error

            });
            _status = ProgramStatusType.Online;
        

            var isRun = await RunEquips(_programId);
           
            // 启动推送
            Timers.Start("PushAndWrite", 1000, async () =>
            {
                if (_isExecute == false)
                {
                    _isExecute = true;
                    await _clientMainManager.PushAndWirte();
                    _isExecute = false;
                }
               
            });


        }




      
        await HandleControls();
    }

    private async Task HandleControls()
    {
        try
        {
            await foreach (var control in _clientMainManager.ReadControl(new IotContract.Models.Clients.ClientRequestCommand
            {
                ProgramId = _programId
            }, _cancellationTokenSource.Token))
            {
                if (control.ControlType == ProgramControlType.Run)
                {
                    await RunEquips(control.ProgramId);
                }
                else if (control.ControlType == ProgramControlType.Connect)
                {
                    await RunEquips(control.ProgramId, control.EquipId);
                }
            }
        }
        catch (Exception)
        {
            await Task.Delay(5000);
            await HandleControls();
        }

    }
    /// <summary>
    /// 启动设备
    /// </summary>
    /// <returns></returns>
    private async Task<bool> RunEquips(long programId, long equipId = 0)
    {

        // 读取设备数据
        var msgData = await _connectDataService.GetEquips(new IotContract.Models.Clients.ClientRequestCommand
        {
            ProgramId = programId,
            EquipId = equipId

        });
        if (msgData.Item2.IsNotNullOrEmpty())
        {
            _error = $"Error Run Equips，{msgData.Item2}";
            _logService.LogError(_error);
            return false;
        }
        else
        {

            var equips = msgData.Item1;

            if (equips == null || equips.Count == 0)
            {
                _error = $"Get No Equips,Not Run";
                _logService.Log(_error);
                return false;

            }
            else
            {
                if (equipId == 0)
                {
                    await _clientMainManager.Stop(_programId);
                }

                await _clientMainManager.Run(equips);

                _error = $"Success Run Equips {equips.Count}";
                _logService.Log(_error);

                _status = ProgramStatusType.Running;

                return true;


            }


        }
    }
    public async override Task Stop()
    {
        _cancellationTokenSource?.Cancel();

        _logService.Log("WebClient Stop");

        // 上报状态

        await _connectDataService.CommitStatus(new IotContract.Models.Clients.ClientStatusCommand
        {
            ProgramId = _programId,
            Name = _programName,
            Status = ProgramStatusType.Offline,
            StatusDes = "WebClient Stop"

        });

        await _signalRService.StopServer();

        StopBase();
    }
    /// <summary>
    /// 连接SignalR
    /// </summary>
    /// <returns></returns>
    public async Task<bool> ConnectSignalR()
    {
        if (_programName.IsNullOrEmpty())
        {
            return false;
        }
       
        var address = _connectDataService.AddressConfig;
        // 连接SignalR服务，推送日志和消息
        var result = await _signalRService.ConnectServer(address.AdminUrl, new User
        {
            ID = Guid.NewGuid().ToString(),
            Name = _programName,
            Type = DeviceEnum.Service
        });
        return result;
    }


   
}
